
import 'dart:convert';

import 'package:sqflite/sqflite.dart';
import 'package:sqflite/sqlite_api.dart';
import 'package:xreader/common/app_config.dart';
import 'package:xreader/db/base_db_provider.dart';
import 'package:xreader/generated/json/base/json_convert_content.dart';
import 'package:xreader/logs/log.dart';
import 'package:xreader/model/fan_yi_entity.dart';
import 'package:xreader/model/t_book_cont_entity.dart';
import 'package:xreader/params/book_cont_params.dart';

class TBookContProvider extends  BaseDbProvider{
  static final String TABLE_NAME = AppConfig.t_book_cont;
  static final String column_id = "id";
  static final String column_phk = "phk";
  static final String column_btitle = "btitle";
  static final String column_bookid = "bookid";
  static final String column_border = "border";
  static final String column_bnum = "bnum";
  static final String column_bcont_num = "bcont_num";
  static final String column_fanyis_num = "fanyis_num";
  static final String column_bcontstr = "bcontstr";
  static final String column_tmsec = "tmsec";

  Map<String,dynamic> toMap(TBookContEntity po){
    Map<String,dynamic> info = {
      column_id:po.id,
      column_phk:po.phk,
      column_btitle:po.btitle,
      column_bookid:po.bookid,
      column_border:po.border,
      column_bcont_num:po.bcontNum,
      column_fanyis_num:po.fanyisNum,
      column_bnum:po.bnum,
      column_bcontstr:po.bcontstr,
    };
    return info;
  }



  String _noBlobCols(String tableAlias){
    return ''' 
        ${tableAlias}.${column_id} , 
        ${tableAlias}.${column_phk} , 
        ${tableAlias}.${column_btitle},
        ${tableAlias}.${column_bookid},
        ${tableAlias}.${column_border},
        ${tableAlias}.${column_bcont_num},
        ${tableAlias}.${column_bnum},
        ${tableAlias}.${column_fanyis_num},
        ${tableAlias}.${column_bcontstr}
      ''';
  }

  @override
  String tableName() {
    return TABLE_NAME;
  }

  @override
  String tableSqlString() {
    return '''${tableBaseStringIntegerPrimarkKey(TABLE_NAME, column_id)}      
        $column_phk text,
        $column_btitle text,
        $column_bookid integer,
        $column_border integer,
        $column_bnum integer,
        $column_bcont_num integer,
        $column_fanyis_num integer,
        $column_bcontstr text,
        $column_tmsec integer
        )
      ''';
  }

  //添加书籍索引
  @override
  List<String> tableIndexString() {
    List<String> indexs = <String>[];
    indexs.add(
      '''
        create index ${TABLE_NAME}_bookid_idx on ${TABLE_NAME} ( ${column_bookid} COLLATE BINARY ASC )
      '''
    );
    return indexs;
  }

  _whereSql(StringBuffer sql,BookContParams params){
    String word = params.word ?? "";
    if(word.isNotEmpty){
      sql.write(" and ( t1.${column_btitle} like '%${word}%' or t1.${column_bcontstr} like '%${word}%' )  ");
    }
    if(params.bookid != null){
      sql.write(" and t1.${column_bookid} = ${params.bookid} ");
    }
    if(params.id != null){
      sql.write(" and t1.${column_id} = ${params.id} ");
    }

  }
  void _orderBySql(StringBuffer sb){
    sb.write(" order by  t1.border asc ");
  }

  //获取书籍基本信息
  Future<List<TBookContEntity>> queryBookContBaseInfo(BookContParams params) async {
    Database? db = await getDataBase();
    List<TBookContEntity> datas = [];
    if(db == null){
      return datas;
    }
    String baseCols = _noBlobCols("t1");
    StringBuffer sql = StringBuffer(" select  ${baseCols} from ${TABLE_NAME} t1 where 1=1 ");
    _whereSql(sql, params);
    _orderBySql(sql);
    limitSql(sql, params);
    String rawSql = sql.toString();
    Log.i("SQL==> ${rawSql} ");
    List<Map<String,Object?>> dbRecords = await db.rawQuery(rawSql);
    for(Map<String,Object?> obj in dbRecords){
      datas.add(TBookContEntity.fromJson(obj));
    }
    return datas;
  }

  Future<Set<int>> getBookChapterIds(int bookid) async {
    Set<int> ids = {};
    Database? db = await getDataBase();
    if(db == null){
      return ids;
    }
    String sql = "select id from ${TABLE_NAME} where $column_bookid = ${bookid}";
    List<Map<String,Object?>> datas = await db.rawQuery(sql);
    for(Map<String,Object?> data in datas){
      Object? idObj = data["$column_id"];
      int? id = jsonConvert.convert<int>(idObj);
      if(id != null){
        ids.add(id);
      }
    }
    return ids;
  }
  //统计总数
  Future<int?> countBookContBaseInfo(BookContParams params) async {
    Database? db = await getDataBase();
    if(db == null){
      return 0;
    }
    StringBuffer sql = StringBuffer(" select  count(1) from ${TABLE_NAME} t1 where 1=1 ");
    _whereSql(sql, params);
    String rawSql = sql.toString();
    Log.i("SQL==> ${rawSql} ");
    return Sqflite.firstIntValue(await db.rawQuery(rawSql));
  }
  insertDatas(List<TBookContEntity>? datas) async{
    if(datas == null || datas.isEmpty){
      return;
    }
    Database? db = await getDataBase();
    if(db == null){
      return;
    }
    var batch = db.batch();
    datas.forEach((info) {
      batch.insert(TABLE_NAME, toMap(info),conflictAlgorithm: ConflictAlgorithm.ignore);
    });
    await batch.commit(noResult: true);
  }

  //获取某个章节具体
  Future<TBookContEntity> getById(int id) async {
    TBookContEntity po = TBookContEntity();
    Database? db = await getDataBase();
    if(db == null){
      return po;
    }
    String rawSql = " select * from ${TABLE_NAME} where id = ${id} ";
    List<Map<String,Object?>> dbRecords = await db.rawQuery(rawSql);
    for(Map<String,Object?> obj in dbRecords){
      po = TBookContEntity.fromJson(obj);
    }
    po.bcontList = [];
    //反序列化
    if(po.bcontstr != null && po.bcontstr!.isNotEmpty){
      try{
        Iterable iterable = jsonDecode(po.bcontstr ?? "[]");
        po.bcontList!.addAll(iterable.map((d) => FanYiEntity.fromJson(d)));
      }catch(e){
        Log.i("id=${po.id} e=${e}");
      }
    }
    return po;
  }



  Future<int> updateSelectiveById(TBookContEntity po ) async {
    if(po.id == null){
      po.id = -1;
    }
    Database? db = await getDataBase();
    if(db == null){
      return 0;
    }
    Map<String,dynamic> updateMap = {};
    if(po.bookid != null){
      updateMap["${column_bookid}"] = po.bookid;
    }
    if(po.bcontList != null){
      po.bcontstr = jsonEncode(po.bcontList);
    }
    if(po.bcontstr != null){
      updateMap["${column_bcontstr}"] = po.bcontstr;
    }
    if(po.fanyisNum != null){
      updateMap["${column_fanyis_num}"] = po.fanyisNum;
    }
    if(po.bcontNum != null){
      updateMap["${column_bcont_num}"] = po.bcontNum;
    }
    if(po.border != null){
      updateMap["${column_border}"] = po.border;
    }
    if(po.bnum != null){
      updateMap["${column_bnum}"] = po.bnum;
    }
    if(po.tmsec != null){
      updateMap["${column_tmsec}"] = po.tmsec;
    }
    int num = await db.update(TABLE_NAME,updateMap,where: " id = ? ",whereArgs: [po.id]);
    return num;
  }

}